/* -----------------
* brief
* 1. this is code gen by tools
* 2. mvc code are driver by the model defined with the same filename,
	 for example:
	 there is a Xmodel struct define in xmodel.go file, after the script run (lego model-mvc module_name xmodel)
     it will auto create the code under the module's path
	 m --> xmodel.go
	 v --> view
	 c --> xmodel_ctrl
* 3. you should modify this code if it doesn't satisfy your purpose
*/

package controller

import (
	"encoding/json"
	"fmt"
	"github.com/chanxuehong/wechat/mch/mmpaymkttransfers/promotion"
	"github.com/chanxuehong/wechat/mch/pay"
	"github.com/mjiulee/lego"
	"github.com/mjiulee/lego/utils"
	"github.com/valyala/fasthttp"
	"saas_sys_base/common"
	. "saas_sys_base/modules/appmanager/service"
	. "saas_sys_base/modules/sysOrders/service"

	. "saas_sys_base/modules/user/service"
	. "saas_sys_base/modules/wechat/service"
)

type SysOrdersApiCtrl struct {

	service                 OrdersService
	detailService           OrderDetailService
	specService             AppProductSpecService

	wxWeappMchPayService WxWeappMchPayService
	wxUserService WxUserService
}

func init() {
	vc := new(SysOrdersApiCtrl)
	vc.wxWeappMchPayService = *NewWxWeappMchPayService()
	_ctrlList = append(_ctrlList, vc)
}

func (vc *SysOrdersApiCtrl) CtrlInfo() string {
	return "OrdersCtrl"
}

func (vc *SysOrdersApiCtrl) RoutInit() {
	//C端接口
	lego.APIPOST("/api/sysOrders/submitOrder", vc.SubmitOrder, true)
	lego.APIPOST("/api/sysOrders/refund", vc.Refund, true)
	lego.APIPOST("/api/sysOrders/withdraw", vc.Withdraw, true)

}

func (vc *SysOrdersApiCtrl) SubmitOrder(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := "success"


    type Request struct {
        ProductId int64 `json:",string"`
        SpecId int64 `json:",string"`
	}

	type Response struct {
		UnifiedOrderResponse *pay.UnifiedOrderResponse
		PaySignResult *pay.PaySignResult `json:",omitempty"`
	}

	var request Request
	var resp Response

	for {
		sessionData := common.GetSessionData(&ctxExt)
		appwho := sessionData.AppTokenWho

		requestByte := ctxExt.PostBody()
		err := json.Unmarshal(requestByte, &request)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		//使用后端预先配置的卡参数作为配置卡数据
		/*err = UpdateCardParaByCardPara(&request.MchCardUnionMsg)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}*/
		wxuser := vc.wxUserService.GetWxUserByUid(appwho.Uid) // TODO这里计划把他封装到调用它的service里，比如order模块里
		if wxuser == nil {
			code = -1
			msg = fmt.Sprintf("not found wxuser by uid<%d>", appwho.Uid)
			break
		}

		sysOrder, orderDetail, err := vc.service.UnifiedOrderByWho(appwho, request.ProductId, request.SpecId)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		UnifiedOrderRequest := new(pay.UnifiedOrderRequest)
		UnifiedOrderRequest.OutTradeNo = utils.Int64ToString(sysOrder.Id)
		UnifiedOrderRequest.TotalFee = int64(orderDetail.SellPrice * 100)
		UnifiedOrderRequest.TradeType = "JSAPI"
		UnifiedOrderRequest.Body = "test"
        UnifiedOrderRequest.OpenId = wxuser.OpenId

		if orderDetail.SellPrice == 0 {
			if err != nil {
				code = -1
				msg = "支付价格不能为0， 请再次确认价格"
				break
			}
		}

		result, paySignResult, err := vc.wxWeappMchPayService.UnifiedorderByAppWho(appwho, UnifiedOrderRequest, common.PAY_TO_SYS)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		resp.UnifiedOrderResponse = result
		resp.PaySignResult = paySignResult
		response["data"] = resp
		break
	}

	response["code"] = code
	response["msg"] = msg

	ctxExt.JSON(200, response)

}


func (vc *SysOrdersApiCtrl) Refund(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := "success"


	type Request struct {
		OutTradeNo string `vd:"len($)>0"`
	}

	type Response struct {
		RefundResponse *pay.RefundResponse
	}

	var request Request
	var resp Response

	for {
		sessionData := common.GetSessionData(&ctxExt)
		appwho := sessionData.AppTokenWho

		requestByte := ctxExt.PostBody()
		err := json.Unmarshal(requestByte, &request)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		err = lego.Validate(request)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}
		//使用后端预先配置的卡参数作为配置卡数据
		/*err = UpdateCardParaByCardPara(&request.MchCardUnionMsg)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}*/
		wxuser := vc.wxUserService.GetWxUserByUid(appwho.Uid) // TODO这里计划把他封装到调用它的service里，比如order模块里
		if wxuser == nil {
			code = -1
			msg = fmt.Sprintf("not found wxuser by uid<%d>", appwho.Uid)
			break
		}

		OutTraderId, err := utils.StringToInt64(request.OutTradeNo)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		resp.RefundResponse, err = vc.service.RefundByWho(appwho, OutTraderId)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		response["data"] = resp
		break
	}

	response["code"] = code
	response["msg"] = msg

	ctxExt.JSON(200, response)

}


//向平台提现
func (vc *SysOrdersApiCtrl) Withdraw(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := "success"


	type Request struct {
		*promotion.TransferReqPara
	}

	type Response struct {
		TransferResp *promotion.TransferRespData
	}

	var request Request
	var resp Response

	for {
		sessionData := common.GetSessionData(&ctxExt)
		appwho := sessionData.AppTokenWho

		requestByte := ctxExt.PostBody()
		err := json.Unmarshal(requestByte, &request)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		err = lego.Validate(request)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}
		//使用后端预先配置的卡参数作为配置卡数据
		/*err = UpdateCardParaByCardPara(&request.MchCardUnionMsg)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}*/
		wxuser := vc.wxUserService.GetWxUserByUid(appwho.Uid) // TODO这里计划把他封装到调用它的service里，比如order模块里
		if wxuser == nil {
			code = -1
			msg = fmt.Sprintf("not found wxuser by uid<%d>", appwho.Uid)
			break
		}



		resp.TransferResp, err = vc.service.WithdrawByWho(appwho, request.TransferReqPara)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		response["data"] = resp
		break
	}

	response["code"] = code
	response["msg"] = msg

	ctxExt.JSON(200, response)

}